<!--
 * @Description: 价格趋势图表组件
 * @Date: 2025-10-10
-->
<template>
  <view class="chart-container">
    <!-- 时间周期选择 -->
    <view class="period-tabs">
      <view 
        class="period-tab" 
        :class="{ active: activePeriod === '1d' }"
        @tap="changePeriod('1d')"
      >
        1天
      </view>
      <view 
        class="period-tab" 
        :class="{ active: activePeriod === '3d' }"
        @tap="changePeriod('3d')"
      >
        3天
      </view>
      <view 
        class="period-tab" 
        :class="{ active: activePeriod === '7d' }"
        @tap="changePeriod('7d')"
      >
        7天
      </view>
    </view>

    <!-- 图表区域 -->
    <view class="chart-area" ref="chartArea">
      <canvas 
        canvas-id="priceChart" 
        :style="{ width: chartWidth + 'px', height: chartHeight + 'px' }"
        @touchstart="handleTouchStart"
        @touchmove="handleTouchMove"
        @touchend="handleTouchEnd"
      />
      
      <!-- 价格提示框 -->
      <view 
        class="price-tooltip" 
        v-if="showTooltip"
        :style="{ left: tooltipX + 'px', top: tooltipY + 'px' }"
      >
        <view class="tooltip-time">{{ tooltipData.time }}</view>
        <view class="tooltip-price">{{ formatPrice(tooltipData.price) }}个</view>
      </view>
    </view>

    <!-- 价格统计 -->
    <view class="price-stats">
      <view class="stat-item">
        <view class="stat-label">最高</view>
        <view class="stat-value high">{{ formatPrice(priceStats.max) }}</view>
      </view>
      <view class="stat-item">
        <view class="stat-label">最低</view>
        <view class="stat-value low">{{ formatPrice(priceStats.min) }}</view>
      </view>
      <view class="stat-item">
        <view class="stat-label">平均</view>
        <view class="stat-value avg">{{ formatPrice(priceStats.avg) }}</view>
      </view>
      <view class="stat-item">
        <view class="stat-label">波动</view>
        <view class="stat-value" :class="priceStats.changePercent >= 0 ? 'up' : 'down'">
          {{ priceStats.changePercent >= 0 ? '+' : '' }}{{ priceStats.changePercent.toFixed(1) }}%
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'PriceChart',
  props: {
    currencyData: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      activePeriod: '1d',
      chartWidth: 300,
      chartHeight: 200,
      showTooltip: false,
      tooltipX: 0,
      tooltipY: 0,
      tooltipData: {},
      ctx: null
    }
  },
  
  computed: {
    // 当前周期的价格数据
    currentPriceData() {
      return this.currencyData.history[this.activePeriod] || [];
    },
    
    // 价格统计
    priceStats() {
      const prices = this.currentPriceData.map(item => item.price);
      if (prices.length === 0) {
        return { max: 0, min: 0, avg: 0, changePercent: 0 };
      }
      
      const max = Math.max(...prices);
      const min = Math.min(...prices);
      const avg = prices.reduce((sum, price) => sum + price, 0) / prices.length;
      const firstPrice = prices[0];
      const lastPrice = prices[prices.length - 1];
      const changePercent = firstPrice > 0 ? ((lastPrice - firstPrice) / firstPrice) * 100 : 0;
      
      return { max, min, avg, changePercent };
    }
  },
  
  mounted() {
    this.$nextTick(() => {
      this.initChart();
    });
  },
  
  watch: {
    activePeriod() {
      this.$nextTick(() => {
        this.drawChart();
      });
    },
    
    currencyData: {
      handler() {
        this.$nextTick(() => {
          this.drawChart();
        });
      },
      deep: true
    }
  },
  
  methods: {
    // 初始化图表
    initChart() {
      const query = uni.createSelectorQuery().in(this);
      query.select('.chart-area').boundingClientRect(rect => {
        if (rect) {
          this.chartWidth = rect.width - 20;
          this.chartHeight = 200;
          
          this.ctx = uni.createCanvasContext('priceChart', this);
          this.drawChart();
        }
      }).exec();
    },
    
    // 切换时间周期
    changePeriod(period) {
      this.activePeriod = period;
      this.showTooltip = false;
    },
    
    // 绘制图表
    drawChart() {
      if (!this.ctx || this.currentPriceData.length === 0) return;
      
      const { ctx, chartWidth, chartHeight } = this;
      const data = this.currentPriceData;
      const padding = 20;
      const plotWidth = chartWidth - padding * 2;
      const plotHeight = chartHeight - padding * 2;
      
      // 清空画布
      ctx.clearRect(0, 0, chartWidth, chartHeight);
      
      // 计算价格范围
      const prices = data.map(item => item.price);
      const minPrice = Math.min(...prices);
      const maxPrice = Math.max(...prices);
      const priceRange = maxPrice - minPrice || 1;
      
      // 绘制网格线
      ctx.setStrokeStyle('#f0f0f0');
      ctx.setLineWidth(1);
      
      // 水平网格线
      for (let i = 0; i <= 4; i++) {
        const y = padding + (plotHeight / 4) * i;
        ctx.beginPath();
        ctx.moveTo(padding, y);
        ctx.lineTo(chartWidth - padding, y);
        ctx.stroke();
      }
      
      // 垂直网格线
      const stepX = plotWidth / Math.max(data.length - 1, 1);
      for (let i = 0; i < data.length; i++) {
        const x = padding + stepX * i;
        ctx.beginPath();
        ctx.moveTo(x, padding);
        ctx.lineTo(x, chartHeight - padding);
        ctx.stroke();
      }
      
      // 绘制价格线
      ctx.setStrokeStyle('#f4c242');
      ctx.setLineWidth(2);
      ctx.beginPath();
      
      data.forEach((item, index) => {
        const x = padding + stepX * index;
        const y = padding + plotHeight - ((item.price - minPrice) / priceRange) * plotHeight;
        
        if (index === 0) {
          ctx.moveTo(x, y);
        } else {
          ctx.lineTo(x, y);
        }
      });
      
      ctx.stroke();
      
      // 绘制数据点
      ctx.setFillStyle('#f4c242');
      data.forEach((item, index) => {
        const x = padding + stepX * index;
        const y = padding + plotHeight - ((item.price - minPrice) / priceRange) * plotHeight;
        
        ctx.beginPath();
        ctx.arc(x, y, 4, 0, 2 * Math.PI);
        ctx.fill();
      });
      
      // 绘制渐变填充
      const gradient = ctx.createLinearGradient(0, padding, 0, chartHeight - padding);
      gradient.addColorStop(0, 'rgba(244, 194, 66, 0.3)');
      gradient.addColorStop(1, 'rgba(244, 194, 66, 0.05)');
      ctx.setFillStyle(gradient);
      
      ctx.beginPath();
      ctx.moveTo(padding, chartHeight - padding);
      data.forEach((item, index) => {
        const x = padding + stepX * index;
        const y = padding + plotHeight - ((item.price - minPrice) / priceRange) * plotHeight;
        ctx.lineTo(x, y);
      });
      ctx.lineTo(chartWidth - padding, chartHeight - padding);
      ctx.closePath();
      ctx.fill();
      
      ctx.draw();
    },
    
    // 触摸开始
    handleTouchStart(e) {
      this.handleTouch(e);
    },
    
    // 触摸移动
    handleTouchMove(e) {
      this.handleTouch(e);
    },
    
    // 触摸结束
    handleTouchEnd() {
      setTimeout(() => {
        this.showTooltip = false;
      }, 2000);
    },
    
    // 处理触摸事件
    handleTouch(e) {
      if (this.currentPriceData.length === 0) return;
      
      const touch = e.touches[0];
      const padding = 20;
      const plotWidth = this.chartWidth - padding * 2;
      const stepX = plotWidth / Math.max(this.currentPriceData.length - 1, 1);
      
      // 计算最近的数据点
      const relativeX = touch.x - padding;
      const dataIndex = Math.round(relativeX / stepX);
      
      if (dataIndex >= 0 && dataIndex < this.currentPriceData.length) {
        const dataPoint = this.currentPriceData[dataIndex];
        
        this.tooltipData = {
          time: this.activePeriod === '1d' ? dataPoint.time : dataPoint.date,
          price: dataPoint.price
        };
        
        this.tooltipX = Math.min(Math.max(touch.x - 50, 0), this.chartWidth - 100);
        this.tooltipY = touch.y - 60;
        this.showTooltip = true;
      }
    },
    
    // 格式化价格
    formatPrice(price) {
      if (price >= 1000) {
        return (price / 1000).toFixed(1) + 'K';
      } else if (price >= 1) {
        return price.toFixed(2);
      } else if (price >= 0.1) {
        return price.toFixed(3);
      } else {
        return price.toFixed(4);
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.chart-container {
  background: white;
  border-radius: 15rpx;
  padding: 20rpx;
  margin: 20rpx 0;
}

.period-tabs {
  display: flex;
  margin-bottom: 20rpx;
  background: #f8f9fa;
  border-radius: 25rpx;
  padding: 6rpx;
}

.period-tab {
  flex: 1;
  text-align: center;
  padding: 16rpx;
  font-size: 26rpx;
  color: #666;
  border-radius: 20rpx;
  transition: all 0.3s ease;
  
  &.active {
    background: #f4c242;
    color: white;
    font-weight: bold;
  }
}

.chart-area {
  position: relative;
  padding: 20rpx 0;
}

.price-tooltip {
  position: absolute;
  background: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 16rpx 20rpx;
  border-radius: 10rpx;
  font-size: 24rpx;
  z-index: 10;
  pointer-events: none;
  
  &::after {
    content: '';
    position: absolute;
    bottom: -10rpx;
    left: 50%;
    transform: translateX(-50%);
    border: 10rpx solid transparent;
    border-top-color: rgba(0, 0, 0, 0.8);
  }
}

.tooltip-time {
  font-size: 22rpx;
  opacity: 0.8;
  margin-bottom: 4rpx;
}

.tooltip-price {
  font-weight: bold;
  font-size: 26rpx;
}

.price-stats {
  display: flex;
  justify-content: space-around;
  margin-top: 20rpx;
  padding-top: 20rpx;
  border-top: 1px solid #f0f0f0;
}

.stat-item {
  text-align: center;
}

.stat-label {
  font-size: 22rpx;
  color: #999;
  margin-bottom: 8rpx;
}

.stat-value {
  font-size: 26rpx;
  font-weight: bold;
  
  &.high { color: #f56c6c; }
  &.low { color: #67c23a; }
  &.avg { color: #409eff; }
  &.up { color: #f56c6c; }
  &.down { color: #67c23a; }
}
</style>